package com.zc.auth.security.core.access.meta;

import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.util.StringUtils;

import java.util.Collection;
import java.util.Map;
import java.util.Set;

/**
 * redis元数据管理
 *
 * @author zcj
 * @version 1.0.0
 * @date 2022/5/13 14:28
 */
public class RedisUrlRoleMetaDataManager implements UrlRoleMetaDataManager {

    private static final String KEY_PREFIX = "zc:auth:role:metadata";

    private PathMatcher pathMatcher = new AntPathMatcher();

    @Autowired
    private StringRedisTemplate redisTemplate;

    private String serverName;

    public RedisUrlRoleMetaDataManager(String serverName) {
        this.serverName = serverName;
    }

    @Override
    public Collection<String> getAccessibleRoles(String url) {
        return this.getAccessibleRoles(url, this.getUrlsAndRolesMap());
    }

    @Override
    public Collection<String> getAccessibleRoles(String url, Map<String, ? extends Collection<String>> map) {
        if (map == null) {
            return null;
        }
        for (Map.Entry<String, ? extends Collection<String>> entry : map.entrySet()) {
            if (this.pathMatcher.match(entry.getKey(), url)) {
                return entry.getValue();
            }
        }
        return null;
    }

    @Override
    public void updateRedisUrlsAndRolesMap(Map<String, Set<String>> map, String serverName) {
        UrlPattenRoleCollect pattenRoleCollect = new UrlPattenRoleCollect();
        pattenRoleCollect.setUrlRoleMap(map);
        this.redisTemplate.opsForValue().set(getFullKey(serverName), JSON.toJSONString(pattenRoleCollect));
    }

    @Override
    public Map<String, Set<String>> getUrlsAndRolesMap() {
        String content = this.redisTemplate.opsForValue().get(this.getFullKey());
        if (!StringUtils.hasLength(content)) {
            return null;
        }
        UrlPattenRoleCollect urlPattenRoleCollect = JSON.parseObject(content, UrlPattenRoleCollect.class);
        return urlPattenRoleCollect.getUrlRoleMap();
    }

    /**
     * 获取redis key
     *
     * @return
     */
    private String getFullKey() {
        return this.getFullKey(this.serverName);
    }

    /**
     * 获取redis key
     *
     * @param key
     * @return
     */
    private String getFullKey(String key) {
        return KEY_PREFIX + ":" + key;
    }


}
